
=begin
class Service
  Pattern::Property.enable(self, :input)
  Pattern::Property.enable(self, :output)


  class Validator
    def error o
       raise "#{o.inspect} does not pass #{self.class}."
    end

    def validate o
      validates?(o) || error(o)
    end
  end

  class IntegerValidator < Validator
    def initialize params

    end

    def validates? o
      o.is_a? Fixnum
    end
  end

  VALIDATORS = {
    :integer => IntegerValidator
  }

  def initialize input
    input input
  end

  def input input
    (Pattern::Property.property_names self.class, :input).
      each { |property|
        validate property, input[property]
        self.send(
          property.to_s+'=',
          input[property]
        )
      }
    self
  end

  def validate name, value
    if definition = Pattern::Property.definition(self.class, name)
      VALIDATORS[definition[0]].new(definition[1] || {}).validate value
    end
  end

  def execute
    result = {}
    (Pattern::Property.property_names self.class, :output).
      each { |output|
        value = self.send(output)
        validate output, value
        result[output] = value
      }
    result
  end


  class Test < FwTest

    class AddOne < Service
      input :number, :integer
      output :result, :integer

      def result
        number + 1
      end
    end

    def test_api_call
      eq AddOne.new({:number => 1}).execute, :result => 2
    end

    def test_bad_input_type_raises_error
      assert_raise(RuntimeError) {
        AddOne.new({:number => '5'}).execute
      }
      
    end

    class ServiceThatShouldReturnInteger < Service
      output :result, :integer

      def result
        "error"
      end
    end

    def test_bad_return_type_raises_error
      assert_raise(RuntimeError) {
        ServiceThatShouldReturnInteger.
          new({}).execute
      }
    end

  end
end
=end